home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
1833
/
1833.xpi
/
chrome
/
yoono.jar
/
content
/
yoono
/
bookmarks
/
bookmarksxopml.js
< prev
next >
Wrap
Text File
|
2009-12-16
|
16KB
|
535 lines
/*
* bookmarksxbel.js
*
* @author david marteau <marteau.david@free.fr>
* @copyright 2005-2006 Yoono
*/
function ynListOfLinks( aBaseURI )
{
this.baseURI = aBaseURI;
this.links = [];
}
ynListOfLinks.prototype =
{
copy : function( aBaseURI )
{
var newList = new ynListOfLinks(aBaseURI);
for(var i=0;i<this.links.length;++i)
newList.append(this.links[i]);
return newList;
},
append : function( aURI ) {
this.links.push(aURI);
},
contains : function( aURI )
{
for(var i=0;i<this.links.length;++i) {
if(this.links[i].equals(aURI))
return true;
}
return false;
},
get spec() { return this.baseURI.spec; },
toString : function()
{
var str = "base URI: "+ this.baseURI.spec + "\n";
for(var i=0;i<this.links.length;++i) {
str += i+". "+this.links[i].spec+"\n";
}
return str;
}
};
//====================================================
// OPML Driver
//====================================================
function ynOPMLIOService()
{
this._bmUtils = new ynBookmarksUtils();
this._yns = new Namespace(YOONO_NS);
this._owner = "firefox-yoono-extension";
this._ioSrvc = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
this._allowDuplicateURL = this._bmUtils.getPref("extensions.yoono.import.allowDuplicateURL",false );
this._allowRemoteURL = this._bmUtils.getPref("extensions.yoono.import.allowRemoteURL" ,false);
}
ynOPMLIOService.prototype =
{
/*
* import xbel xmlObject in 'root' folder
*/
_import : function( opmlBody, root, rootLinks )
{
var foldersets=[[opmlBody,root,rootLinks]];
var folderset=null;
var bmUtils = this._bmUtils;
var yns = this._yns;
var owner = this._owner;
var duplicate = this._allowDuplicateURL;
var remote = this._allowRemoteURL;
var opmlFileExt = /\.opml$/;
const urlRes = bmUtils.getArc("URL");
const nameRes = bmUtils.getArc("Name");
/*
* Import node as folder, handle replication
*/
function importAsFolder( opml, text, description, parent, returned )
{
var res = null;
var resource = null;
// Find the parent folder if no duplicate allowed
// Otherwise just add a new folder
if(!duplicate) // No duplicate allowed
resource = bmUtils.getBookmarkedResource(nameRes,text);
if(!resource)
{
// XXX Need to set parent for setting description
res = resource = (description ?
bmUtils.createFolder(text,description,parent) :
bmUtils.createFolder(text,null,null));
}
if(opml && resource)
foldersets.push([opml,resource,returned.links]);
if(returned)
returned.value = resource;
return res;
}
/*
* Preload links
*/
var resourcesLinks = this._resourcesLinks;
var ioSrvc = this._ioSrvc;
function preLoadLink( url,text,description,parent, folderLinks )
{
bmUtils.error("yoono:opml","preload :"+url+"\n"+folderLinks.toString());
// Only link to local file allowed
if(!remote && url.substr(0,5)!= "file:") {
bmUtils.error("yoono:opml","remote file dropped\n"+url);
return null;
}
var uri = ioSrvc.newURI(url, null, null);
// Check for recursivity
if(folderLinks && folderLinks.contains(uri)) {
bmUtils.error("yoono:opml","recursive link dropped\n"+uri.spec);
return null;
}
if(folderLinks)
folderLinks = folderLinks.copy(uri);
else
folderLinks = new ynListOfLinks(uri);
folderLinks.append(uri);
var returned = { links: folderLinks };
var res = importAsFolder(null,text,description,parent,returned);
if(returned.value)
resourcesLinks.push([folderLinks,returned.value]);
return res;
}
// Loop over folders
while(foldersets.length>0)
{
folderset=foldersets.shift();
var folder = folderset[0];
var parent = folderset[1];
var folderLinks = folderset[2];
var parentContainer = bmUtils.getContainer(parent);
var numItems = 0;
// Loop over child nodes
for each (var element in folder.outline)
{
var res = null;
var text = element.@text.toString();
var description = element.@description.toString();
switch(element.@type.toString())
{
case "include" : {
var url = element.@url.toString();
res = preLoadLink( url,text,description,parent,folderLinks );
if(res) numItems++;
} break;
case "link": {
var url = element.@url.toString();
if(url.match(opmlFileExt))
{
// This is a link to an external opml resource
// Try to import that ressource as a folder
res = preLoadLink( url,text,description,parent,folderLinks );
if(res) numItems++;
}
else
{
// Find a standard url ?
// Import as standard bookmark
if(duplicate || !bmUtils.isBookmarked(urlRes,url)) {
var shortcutUrl = element.@yns::keywords.toString();
res = bmUtils.createBookmark(text,url,shortcutUrl,
description,
null);
numItems++;
}
}
} break;
case "rss" : {
var url = element.@htmlUrl.toString();
if(duplicate || !bmUtils.isBookmarked(urlRes,url))
{
var name = element.@title.toString();
var urlfeed = element.@xmlUrl.toString();
res = bmUtils.createLivemark(name,url,urlfeed,
description,
null);
numItems++;
}
} break;
default: {
/*
* Handle special types
*/
if(element.@yns::type == "separator") {
// Add separator only if items have been inserted
// before. This prevent useless separators to be
// displayed.
if(numItems>0)
res = bmUtils.createSeparator();
break;
}
if(element.@yns::type == "folder") {
// Add as folder only if it is empty
// Because non empty <outline>'s are handled below
if(element.outline.length()==0)
res = importAsFolder(element,text,description,parent,{links:folderLinks});
break;
}
} break;
}
if(res) {
var index = parentContainer.IndexOf(res);
if(index == -1)
parentContainer.AppendElement(res);
}
// If there is <outline> childs then include as folder
if(element.outline.length()>0) {
res = importAsFolder(element,text,description,parent,{links:folderLinks});
if(res) {
var index = parentContainer.IndexOf(res);
if(index == -1)
parentContainer.AppendElement(res);
}
}
}
}
},
/*
* export 'root' folder to opml xmlObject
*/
_export : function( opml, root )
{
var bmUtils = this._bmUtils;
var yns = this._yns;
var owner = this._owner;
const RDF = bmUtils.RDF;
const RDFC = bmUtils.RDFC;
const nsIRDFResource = Components.interfaces.nsIRDFResource;
const urlRes = bmUtils.getArc("URL");
const nameRes = bmUtils.getArc("Name");
const descRes = bmUtils.getArc("Description");
const keywordRes = bmUtils.getArc("ShortcutURL");
const iconRes = bmUtils.getArc("Icon");
const feedRes = bmUtils.getArc("FeedURL");
const dateRes = bmUtils.getArc("BookmarkAddDate");
var ds = bmUtils.BKMS;
var foldersets = [[opml,root]];
var folderset = null;
var nodetree = [];
while(foldersets.length>0)
{
folderset = foldersets.shift();
var folder = folderset[0];
var parent = folderset[1];
var parentContainer = bmUtils.getContainer(parent);
var elements = parentContainer.GetElements();
var subtree = [];
while (elements.hasMoreElements())
{
var res = elements.getNext().QueryInterface(nsIRDFResource);
var separator = false;
var isFolder = false;
var element = null;
var type = bmUtils.getType(res);
switch(type)
{
case "Bookmark": {
var url = bmUtils.getProperty(res,urlRes);
var keywords = bmUtils.getProperty(res,keywordRes);
if(keywords)
element = <outline type="link" link={url} xmlns:yns={YOONO_NS}
yns:keywords={keywords}/>;
else
element = <outline type="link" url={url}/>;
}
break;
case "Livemark": {
var htmlUrl = bmUtils.getProperty(res,urlRes);
var xmlUrl = bmUtils.getProperty(res,feedRes);
var title = bmUtils.getProperty(res,nameRes);
element = <outline htmlUrl={htmlUrl}
xmlUrl={xmlUrl}
title={title}
language="unknown"
type="rss"/>;
}
break;
case "Folder":
case "ToolbarFolder":
element = <outline yns:type="folder" xmlns:yns={YOONO_NS}/>;
foldersets.push([element,res]);
break;
case "BookmarkSeparator":
element = <outline yns:type="separator" xmlns:yns={YOONO_NS}/>;
separator = true;
break;
}
if(element)
{
element.@text = bmUtils.getProperty(res,nameRes);
if(!separator)
{
var description = bmUtils.getProperty(res,descRes);
if(description)
element.@description = description;
}
subtree.push([element,folder]);
}
}
nodetree = nodetree.concat(subtree.reverse());
}
while(nodetree.length>0)
{
var node = nodetree.pop();
node[1].* += node[0];
}
return opml;
},
/*
* Import opml from external link
* XXX Should be asynchronous !
*/
_importLink : function( uri )
{
try {
this._bmUtils.error("yoono:opml","Loading remote file\n"+uri.spec);
var channel = this._ioSrvc.newChannelFromURI( uri )
.QueryInterface(Components.interfaces.nsIChannel);
var input = channel.open();
var sis = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
sis.init(input);
var buffer = sis.read(sis.available());
input.close();
//------------
// Parse buffer
// Use DOM parser for validating xml
//------------
var parser = new DOMParser();
var xmldoc = parser.parseFromString(buffer,"text/xml");
var root = xmldoc.documentElement;
if ((root.tagName == "parsererror") ||
(root.namespaceURI == "http://www.mozilla.org/newlayout/xml/parsererror.xml"))
{
throw(this.getString("xmlparsererror"));
}
// Get the opml node from it
var xmlnode = xmldoc.getElementsByTagName("opml")[0];
if(xmlnode)
{
var xmlstring = new XMLSerializer().serializeToString(xmlnode);
return (new XML(xmlstring)).body;
}
} catch(e) {
this._bmUtils.error("yoono:opml:",e);
}
return null;
},
/*
* Create an opml header
*/
createOpmlHeader : function( title,desc,ownerName,ownerEmail,ownerId )
{
var date = (new Date()).toUTCString();
var opmlhead =
<head>
<title>{title}</title>
<dateCreated>{date}</dateCreated>
</head>;
if(desc)
opmlhead.* += <description>{desc}</description>;
if(ownerName)
opmlhead.* += <ownerName>{ownerName}</ownerName>;
if(ownerEmail)
opmlhead.* += <ownerEmail>{ownerEmail}</ownerEmail>;
if(ownerId)
opmlhead.* += <ownerId>{ownerId}</ownerId>;
return opmlhead;
},
/*
* Export bookmarks to OPML2 format
*/
exportBookmarks : function ( ownerName, ownerEmail, ownerId )
{
var bmUtils = this._bmUtils;
var opml = <opml version="2.0" xmlns:yns={YOONO_NS}/>;
var bmRoot = bmUtils.getRoot();
var title = bmUtils.getPropertyByName(bmRoot,"Name");
var desc = bmUtils.getPropertyByName(bmRoot,"Description");
opml.* += this.createOpmlHeader(title,desc,ownerName,ownerEmail,ownerId);
opml.* += this._export(<body/>,bmRoot);
return opml;
},
/*
* Import bookmarks from OPML2 format
*/
importBookmarks : function ( opml, aBookmarkFolder, baseURI )
{
if(!aBookmarkFolder)
aBookmarkFolder = this._bmUtils.getRoot();
this._resourcesLinks = [];
this._bmUtils.beginUpdateBatch();
var except;
try {
var baseLinks = null;
var yns = this._yns;
if(baseURI) {
baseLinks = new ynListOfLinks(baseURI);
baseLinks.append(baseURI);
}
// Import current node;
this._import(opml.body,aBookmarkFolder,baseLinks);
// Import remote links
while( this._resourcesLinks.length>0 )
{
var resourceLink = this._resourcesLinks.shift();
var links = resourceLink[0];
var resource = resourceLink[1];
opml = this._importLink(links.baseURI);
this._import(opml,resource,links);
}
} catch(ex) {
except = ex;
}
this._bmUtils.flush();
this._bmUtils.endUpdateBatch();
if(except)
throw except;
}
};